local blaze = require "blaze"
local game = require "club.threecard.texas"
local consts = game.util.consts

local M = game.ui.element()

local log = game.logging.get("seats")

local function get_seat_by_player(self, player)
    if not player or not player.seat then
        return
    end
    local no = game.seat.to_local(player.seat.no)
    return self[no]
end

M.store_watchers = {
    room = {
        ["$"] = function(self, store, state)
            for i = 1, game.seat.MAX_SEAT_NO do
                local seat = self[i]
                seat:set_player(nil)
            end
            for no, player in pairs(state.players) do
                if no > 0 then
                    local local_no = game.seat.to_local(no)
                    local seat = get_seat_by_player(self, player)
                    if seat then
                        seat:set_player(player)
                    else
                        log.error(string.format("座位号越界：no=%s local_no=%s", player.seat.no, local_no))
                    end
                else
                    -- 未入座玩家
                end
            end
        end,
        
        ["玩家进入"] = function(self, store, state, player)
            if player.seat.no == 0 then
                return
            end
            local seat = get_seat_by_player(self, player)
            if not seat then
                log.error(string.format("座位号越界：no=%s local_no=%s", player.seat.no, local_no))
                return
            end
            seat:set_player(player)
        end,

        ["玩家离开"] = function(self, store, state, player)
            if player.seat.no == 0 then
                return
            end
            local seat = get_seat_by_player(self, player)
            if not seat then
                log.error(string.format("座位号越界：no=%s local_no=%s", player.seat.no, local_no))
                return
            end
            seat:set_player(nil)
        end
    },

    ingame = {
        ["$"] = blaze.noop,

        ["筹码变更"] = function(self, store, state, args)
            local player = args.player
            local seat = get_seat_by_player(self, player)
            if not seat then
                return
            end
            local old = args.old
            local current = player.chip
            seat:update_chip(old, current)
        end,

        ["玩家操作"] = function(self, store, state, args)
            local player = args.player
            local seat = get_seat_by_player(self, player)
            if not seat then
                return
            end
            if args.operation_id == consts.flop.id then
                seat:on_flop(args.value)
            elseif args.operation_id == consts.check.id then
                seat:on_check(args.value)
            elseif args.operation_id == consts.call.id then
                seat:on_call(args.value)
            elseif args.operation_id == consts.raise_half_pot.id then
                seat:on_raise_half_pot(args.value)
            elseif args.operation_id == consts.raise_pot.id then
                seat:on_raise_pot(args.value)
            elseif args.operation_id == consts.allin.id then
                seat:on_allin(args.value)
            end
        end,

        ["请求玩家操作"] = function(self, store, state, args)
            if state.current_no < 1 then
                return
            end

            for i = 1, game.seat.MAX_SEAT_NO do
                local seat = self[i]
                if seat.player then
                    local server_no = seat.player.seat.no
                    if server_no == state.current_no then
                        seat:on_turn()
                    else
                        seat:on_wait()
                    end
                end
            end
        end,

        ["下盲注"] = function(self, store, state, args)
            local s_blind_no = game.seat.to_local(state.s_blind_no)
            local l_blind_no = game.seat.to_local(state.l_blind_no)
        
            local s_blind_seat = self[s_blind_no]
            local l_blind_seat = self[l_blind_no]
            s_blind_seat:bet(state.s_blind_value)
            l_blind_seat:bet(state.l_blind_value)
        end,

        ["摊牌"] = function(self, store, state, args)
            local showdown_info = state.showdown_info
            if not showdown_info then
                return
            end
        
            for _, player_info in ipairs(showdown_info) do
                local local_no = game.seat.to_local(player_info.no)
                if local_no ~= 1 then
                    local seat = self[local_no]
                    seat.poker_container:clear()
                    seat.poker_container:mingpai(player_info.card_ids)
                end
            end
        end,

        ["阶段变更"] = function(self, store, state, args, init)
            for i = 1, game.seat.MAX_SEAT_NO do
                self[i]:on_phase_change()
            end
        end,

        ["恢复游戏场景"] = function(self, store, state, args)
            for i = 1, game.seat.MAX_SEAT_NO do
                local seat = self[i]
                seat:clear_scene()
            end

            local scene = state.scene
            local phase_id = scene.phase_id
            if phase_id <= state.phases.ready.id then
                return
            end

            for _, other_player in ipairs(scene.other_players) do
                local local_no = game.seat.to_local(other_player.no)
                local seat = self[local_no]
                if seat then
                    seat.poker_container:mopai(other_player.card_ids)
                end
            end
        
            local self_seat = self[1]
            self_seat.poker_container:mopai(scene.self_player.card_ids)
            if scene.self_player.flop then
                self_seat:on_flop()
            end
        
            if scene.current_no > 0 then
                local local_current_no = game.seat.to_local(scene.current_no)
                local seat = self[local_current_no]
                if seat then
                    seat:on_turn()
                end
            end
        end
    }
}

function M:ctor()
    self.res = "club.threecard.texas/ui/ingame.b:seats"

    local seat = game.require "ui.ingame.seat"
    for i = 1, game.seat.MAX_SEAT_NO do
        self[i] = seat.new(i)
    end
end

function M:on_load()
    self:super("on_load")
    for i = 1, game.seat.MAX_SEAT_NO do
        local seat = self[i]
        local root = self.transform:Find("seat_".. i)
        seat:set_gameobject(root.gameObject, true)
        seat:load()
    end
end

return M